﻿using Dorm.QueryObject;
using Dorm.Testes;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Dorm.Tests
{
    [TestClass]
    public class Update_Tests
    {
        private Database db = new Database();

        //[ClassInitialize]
        //public static void Create_Base(TestContext tc) { InsertDeleteTests.GenerateData(); }

        [TestMethod]
        public void Can_Update_Scalar_And_Child_Properties()
        {
            // First user has 3 permissions and 1 profile (admin)
            var firstUser = db.First(new Query<Person>().Filter(p => p.Name).Contains("1").LoadAll());

            // Changes the scalar Name property
            firstUser.Name = "User 1 UPDATED";

            // Changes the reference Type property
            var secondUserType = db.First(new Query<UserType>().Filter(t => t.Name).Equals("External"));
            firstUser.Type = secondUserType;

            // Clean all the permissions and add a new one.
            firstUser.Permissions.Clear();
            firstUser.Permissions.Add(new Permission { ScreenName = "Screen 4" });

            // Add the "Common User" profile to the user.
            var userProfile = db.First(new Query<Profile>().Filter(p => p.Name).Contains("User"));
            firstUser.Profiles.Add(userProfile);

            try
            {
                // Persists all the changes to the Database
                db.BeginTransaction();
                db.Save(firstUser);
                db.CommitTransaction();
            }
            catch
            {
                db.RollbackTransaction();
            }
            
            // Requeries the user
            var firstUserUpdated = db.First(new Query<Person>().Filter(p => p.Name).Contains("1").LoadAll());

            // Verifies that all changes are effected
            Assert.IsTrue(firstUserUpdated.Name.Contains("UPDATED"));
            Assert.IsTrue(firstUserUpdated.Type.ID == secondUserType.ID);
            Assert.IsTrue(firstUserUpdated.Permissions.Count == 1);
            Assert.IsTrue(firstUserUpdated.Permissions[0].ScreenName == "Screen 4");
            Assert.IsTrue(firstUserUpdated.Profiles.Count == 2);
            Assert.IsTrue(firstUserUpdated.Profiles[1].Name.Contains("User"));

            try
            {
                // Return the user to its original state
                firstUserUpdated.Name = "User 1";
                firstUserUpdated.Type = db.First(new Query<UserType>().Filter(t => t.Name).Equals("Internal"));
                firstUserUpdated.Permissions.Clear();
                firstUserUpdated.Permissions.Add(new Permission { ScreenName = "Screen 1" });
                firstUserUpdated.Permissions.Add(new Permission { ScreenName = "Screen 2" });
                firstUserUpdated.Permissions.Add(new Permission { ScreenName = "Screen 3" });
                firstUserUpdated.Profiles.RemoveAt(1);

                db.BeginTransaction();
                db.Save(firstUserUpdated);
                db.CommitTransaction();
            }
            catch
            {
                db.RollbackTransaction();
            }
        }

        //[ClassCleanup]
        //public static void Clean_Base() { InsertDeleteTests.CleanData(); }
    }
}
